#!/usr/bin/env bash
#MISE depends=["test:build-perf-workspace"]
#MISE description="Run performance tests"
# shellcheck disable=SC2086,SC2129
set -euo pipefail

runs="${RUNS:-1}"
cd perf-workspace
mkdir -p flamegraphs
MISE_DATA_DIR="${MISE_DATA_DIR:-$HOME/.local/share/mise}"
declare -A benchmarks
declare -A alt_benchmarks
names=()

if [ -v MISE_ALT ]; then
	which mise
	which "$MISE_ALT"
fi

time_command() {
	local uncached="$1"
	shift
	local cmd="$1"
	local start_time
	local end_time
	local duration
	local total=0
	shift
	echo "running $cmd $* $runs times..." >&2
	for _ in $(seq 1 $runs); do
		if [ "$uncached" = "uncached" ]; then
			"$cmd" cache clear
		fi
		start_time=$(date +%s%N)
		timeout -v 20 "$cmd" "$@" >/dev/null || true
		end_time=$(date +%s%N)
		duration=$(((end_time - start_time) / 1000000))
		total=$((total + duration))
	done
	echo $((total / runs))
}

benchmark() {
	local name="$1"
	# local uncached_duration
	local cached_duration
	shift
	# uncached_duration=$(time_command uncached mise "$@")
	cached_duration=$(time_command cached mise "$@")
	benchmarks["$name-cached"]=$cached_duration

	if [ -n "${MISE_ALT:-}" ]; then
		# alt_uncached_duration=$(time_command uncached "$MISE_ALT" "$@")
		alt_cached_duration=$(time_command cached "$MISE_ALT" "$@")
		alt_benchmarks["$name-cached"]=$alt_cached_duration
	fi

	names+=("$name")
}

mise install
# Warmup call to prime caches before measuring
mise install >/dev/null 2>&1 || true
if [ -n "${MISE_ALT:-}" ]; then
	"$MISE_ALT" install >/dev/null 2>&1 || true
fi
benchmark install install
# Warmup call to prime caches before measuring
mise ls >/dev/null 2>&1 || true
if [ -n "${MISE_ALT:-}" ]; then
	"$MISE_ALT" ls >/dev/null 2>&1 || true
fi
benchmark ls ls
benchmark bin-paths bin-paths
benchmark task-ls task ls
set +x

get_performance_emoji() {
	local variance="$1"
	if [ ${variance#-} -gt 10 ]; then
		if [ $variance -gt 0 ]; then
			echo "✅ "
		else
			echo "⚠️ "
		fi
	fi
}

get_performance_warning() {
	local name="$1"
	local variance="$2"
	local type="$3"
	if [ ${variance#-} -gt 10 ]; then
		if [ $variance -gt 0 ]; then
			echo "✅  Performance improvement: $name $type is ${variance}%"
		else
			local msg="⚠️  Warning: $name $type performance variance is ${variance}%"
			echo "::warning file=xtasks/test/perf::$msg" >&2
			echo "$msg"
		fi
	fi
}

print_performance_table() {
	local output_file="$1"
	if [ -n "${MISE_ALT:-}" ]; then
		echo "| Command    | $MISE_ALT | mise | Variance |" >>"$output_file"
		echo "|------------|-----------|------|----------|" >>"$output_file"
		for name in "${names[@]}"; do
			# uncached_variance=$(((${alt_benchmarks["$name-uncached"]} - ${benchmarks["$name-uncached"]}) * 100 / ${benchmarks["$name-uncached"]}))
			cached_variance=$(((${alt_benchmarks["$name-cached"]} - ${benchmarks["$name-cached"]}) * 100 / ${benchmarks["$name-cached"]}))

			# uncached_emoji=$(get_performance_emoji "$uncached_variance")
			cached_emoji=$(get_performance_emoji "$cached_variance")

			# printf "| %-10s | %6dms | %s%6dms | %+d%% |\n" \
			#   "$name (uncached)" \
			#   "${alt_benchmarks[\"$name-uncached\"]}" \
			#   "$uncached_emoji" \
			#   "${benchmarks[\"$name-uncached\"]}" \
			#   "$uncached_variance" >>"$output_file"
			printf "| %-10s | %6dms | %s%6dms | %+d%% |\n" \
				"$name (cached)" \
				"${alt_benchmarks["$name-cached"]}" \
				"$cached_emoji" \
				"${benchmarks["$name-cached"]}" \
				"$cached_variance" >>"$output_file"
		done
	else
		echo "| Command    | Time   |" >>"$output_file"
		echo "|------------|--------|" >>"$output_file"
		for name in "${names[@]}"; do
			# printf "| %-10s | %6dms |\n" "$name (uncached)" "${benchmarks[\"$name-uncached\"]}" >>"$output_file"
			printf "| %-10s | %6dms |\n" "$name (cached)" "${benchmarks["$name-cached"]}" >>"$output_file"
		done
	fi
}

print_performance_warnings() {
	local output_file="$1"
	if [ -n "${MISE_ALT:-}" ]; then
		for name in "${names[@]}"; do
			# uncached_variance=$(((${alt_benchmarks["$name-uncached"]} - ${benchmarks["$name-uncached"]}) * 100 / ${benchmarks["$name-uncached"]}))
			cached_variance=$(((${alt_benchmarks["$name-cached"]} - ${benchmarks["$name-cached"]}) * 100 / ${benchmarks["$name-cached"]}))

			# warning=$(get_performance_warning "$name" "$uncached_variance" "uncached")
			# if [ -n "$warning" ]; then
			#   echo "$warning" >>"$output_file"
			# fi
			warning=$(get_performance_warning "$name" "$cached_variance" "cached")
			if [ -n "$warning" ]; then
				echo "$warning" >>"$output_file"
			fi
		done
	fi
}

# Print table to console
print_performance_table "/dev/stdout"

if [ -v GITHUB_STEP_SUMMARY ]; then
	# shellcheck disable=SC2016
	echo '## `xtasks/test/perf`' >>../comment.md
	# echo "" >>../comment.md
	# echo "- NUM_TASKS: $num_tasks" >>../comment.md
	# echo "- NUM_TOOLS: $num_tools" >>../comment.md
	# echo "- RUNS: $runs" >>../comment.md
	# echo "" >>../comment.md

	print_performance_table "../comment.md"
	echo "" >>../comment.md
	print_performance_warnings "../comment.md"
fi
